
#include "util.h"

void print_address(const char * name, uint32_t address){
    struct in_addr addr;
    addr.s_addr = address;
    printf("%s  ---->  %s \n", name, inet_ntoa(addr));
}

void print_eth_address(const char * name, const struct rte_ether_addr * eth_address){
    char buf[RTE_ETHER_ADDR_FMT_SIZE];
    rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_address);
    printf("%s address is %s \n", name, buf);
}

void print_arp_table(){
    struct arp_table_s * __arp_table = arp_table_instance();
    struct in_addr __address;
    for (struct arp_entry_s * iter = __arp_table->entries; iter->next != NULL; iter = iter->next){
        __address.s_addr = iter->ip;
        print_eth_address(inet_ntoa(__address), (struct rte_ether_addr *)&iter->hwaddr);
    }
}

uint16_t icmp_checksum(uint16_t *addr, int count){
    register long sum = 0;
    while(count > 1){
        sum += *(unsigned short *)addr++;
        count -= 2;
    }
    if(count > 0){
        sum += *(unsigned char *)addr;
    }
    while(sum >> 16){
        sum = (sum & 0xffff) + (sum >> 16);
    }
    return ~sum;
}

int get_fd_frombitmap(void) {
    int fd = DEFAULT_FD_NUM;
    for ( ;fd < MAX_FD_COUNT;fd ++) {
        if ((fd_table[fd/8] & (0x1 << (fd % 8))) == 0) {  // 当前位是 0
            fd_table[fd/8] |= (0x1 << (fd % 8));  // 当前位 置1
            return fd;
        }
    }
    return -1;
}

int set_fd_frombitmap(int fd) {  // 清空fd
    if (fd >= MAX_FD_COUNT) return -1;
    fd_table[fd/8] &= ~(0x1 << (fd % 8));
    return 0;
}

struct tcp_stream * get_accept_tcb(uint16_t d_port) {
    struct tcp_stream *apt;
    struct tcp_table *table = get_tcp_instance();
    for (apt = table->links;apt != NULL;apt = apt->next) {
        if (d_port == apt->d_port && apt->fd == -1) {   //  -1 没有分配 fd 的
            return apt;
        }
    }
    return NULL;
}



void * get_host_info_from_fd(int fd){
    struct local_host * host;
    // udp
    for (host = g_hosts; host != NULL; host = host->next){
        if(host->fd == fd){
            return host;
        }
    }

    // tcp
    struct tcp_stream * stream = NULL;
    struct tcp_table *table = get_tcp_instance();
    for (stream = table->links; stream != NULL; stream = stream->next) {
        if (fd == stream->fd) {
            return stream;
        }
    }

#if ENABLE_EPOLL
    // epoll
    struct eventpoll * ep = table->ep;
    if(ep != NULL && ep->fd == fd) {
        return ep;
    }
#endif

    return NULL;
}

struct local_host * get_host_info_from_ip_port(uint32_t d_ip, uint16_t d_port, uint8_t proto){
    struct local_host * host;
    for(host = g_hosts; host != NULL; host = host->next){
        if(d_ip == host->local_ip && d_port == host->local_port && proto == host->protocol){
            return host;
        }
    }
    return NULL;
}

struct tcp_stream * get_tcp_stream_from_fd(int fd){
    void * host_info = get_host_info_from_fd(fd);
    if(host_info == NULL){
        return NULL;
    }
    return (struct tcp_stream *)host_info;
}



void error_print(const char * msg){
    printf("%s \n", msg);
//    rte_exit(EXIT_FAILURE, msg);
}